package apiTestBusiness;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import impl.TestServerBusinessImpl;
import models.HttpResponse;
import models.MyConfig;
import tools.Http;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Objects;

/**
 * Created by yangxianming on 2017/10/9.
 * 1.红色:返回4xx 或5xx;
 * 2.黑色:找不到地址；
 * 3.蓝色:请求超时5秒；
 * 4.黄色:json状态码不符合预期，非json返回跳过这层验证；
 * 5.绿色:正常
 */
public class CheckApiHealth implements TestServerBusinessImpl {
    @Override
    public String doIt(HttpServletRequest request, MyConfig myConfig) {
        JSONObject returnJson = JSON.parseObject("{\"apistatus\":0,\"result\":\"\",\"errorMsg\":\"\"}");

        //读取请求json
        InputStreamReader inputStreamReader;
        BufferedReader bufferedReader;
        String requestInfo = "";

        try {
            inputStreamReader = new InputStreamReader(request.getInputStream(), "UTF-8");
            bufferedReader = new BufferedReader(inputStreamReader);
            String line;
            while ((line = bufferedReader.readLine()) != null)
                requestInfo = requestInfo + line;
        }catch (Exception e){
            //请求流如果出现异常的时候
            returnJson.put("apistatus", "0");
            returnJson.put("errorMsg", e.getMessage());
            return returnJson.toString();
        }

        //解析json对象
        JSONObject checkApi = JSON.parseObject(requestInfo);
        String method = checkApi.getString("method");
        JSONObject header = JSON.parseObject(checkApi.getString("header"));
        JSONObject expectResponse = JSON.parseObject(checkApi.getString("expectResponse"));
        String path = checkApi.getString("path");
        String domain = checkApi.getString("domain");
        String url = domain + path;
        JSONObject responseBody = null;
        String parameter = checkApi.getString("parameter");

        //http请求
        Http http = new Http();
        HttpResponse httpResponse = http.sendRequest(method, header, url, parameter);

        //黑色:找不到地址；
        if (httpResponse.getrCode() == 0 && httpResponse.getResponseResult().contains("Connection refused")){
            returnJson.put("apistatus", "1");
            returnJson.put("result", "black");
            returnJson.put("errorMsg", "Connection refused！The reason lie in METHOD DOMAIN or PORT.");
            return returnJson.toString();
        }
        //蓝色:请求超时30秒；
        if (httpResponse.getrCode() == 0 && httpResponse.getResponseResult().contains("Read timed out")){
            returnJson.put("apistatus", "1");
            returnJson.put("result", "blue");
            returnJson.put("errorMsg", "response timed out");
            return returnJson.toString();
        }
        //4xx和5xx 的异常
        if (httpResponse.getrCode() >= 400 && httpResponse.getrCode() < 600){
            returnJson.put("apistatus", "1");
            returnJson.put("result", "red");
            returnJson.put("errorMsg", "return code is 4xx or 5xx");
            return returnJson.toString();
        }
        //如果返回是json对象判断预期结果是否正确
        if (httpResponse.getResponseResult().substring(0, 1).equals("{")){
            try {
                JSONObject apiReturnJson = JSON.parseObject(httpResponse.getResponseResult());          //这个是返回的数据
                responseBody = expectResponse.getJSONObject("responseBody");  //这个是预期的数据,只轮询第一层json对象
                returnJson.put("apistatus", "1");
                returnJson.put("result", "yellow");
                //遍历预期数据中的所有对象，暂时只验证第一层对象
                for (String key: responseBody.keySet()){
                    if (!Objects.equals(responseBody.get(key), apiReturnJson.get(key))){
                        returnJson.put("errorMsg", "Expect data and Return JSON are not same.");
                        return returnJson.toString();
                    }
                }
            }catch (Exception e){
                returnJson.put("errorMsg", "return JSON format error");
                return returnJson.toString();
            }
        }

        returnJson.put("apistatus", "1");
        returnJson.put("result", "green");
        returnJson.put("errorMsg", "");
        return returnJson.toString();
    }
}
